#include "protocolhandler.h"

ProtocolHandler::ProtocolHandler(QObject *parent)
    : QObject{parent}
{

}

//验证控制类命令输入的合法性
bool ProtocolHandler::validateMessageFormat(const QByteArray &data)
{
    qDebug() << "刚进入验证控制的data: "<< data.toHex();
    // 验证每个字节是否为16进制数
    QRegExp hexRegExp("^[0-9A-Fa-f]+$");
    if (!hexRegExp.exactMatch(data.toHex())) {  // 转换为16进制字符串并检查
        QMessageBox::warning(nullptr, "校验错误", "数据包含非16进制字符。");
        return false;
    }

    // 计算CRC校验码
    QByteArray messageContent = data.mid(0, 6); // 获取前6字节用于CRC校验
    unsigned short calculatedCRC = calculateCRC(messageContent);
    // 以小端形式提取接收到的CRC校验码
    unsigned short receivedCRC = static_cast<unsigned short>(
        static_cast<unsigned char>(data[6]) |
        (static_cast<unsigned char>(data[7]) << 8)
        );

    qDebug() << "验证后的rdata: "<< data.toHex();
    qDebug() << "Calculated CRC:" << QString::number(calculatedCRC, 16);
    qDebug() << "Received CRC:" << QString::number(receivedCRC, 16);

    if (calculatedCRC != receivedCRC) {
        QMessageBox::warning(nullptr, "校验错误", "CRC校验失败。");
        return false;
    }

    return true;  // 所有检查均通过
}
//计算CRC
unsigned short ProtocolHandler::calculateCRC(const QByteArray &data)
{
    unsigned short crc = 0xFFFF; // 初始值
    for (char byte : data)
    {
        crc ^= byte;
        for (int i = 0; i < 8; i++)
        {
            bool odd = crc & 0x0001;
            crc >>= 1;
            if (odd)
            {
                crc ^= 0xA001; // 多项式
            }
        }
    }
    return crc;
}
// CRC公有接口函数
unsigned short ProtocolHandler::publicCalculateCRC(const QByteArray &data)
{
    return calculateCRC(data);
}
//...................................
//分包函数
QList<QByteArray> ProtocolHandler::createPackets(quint8 station, quint8 sid, quint8 count, const QByteArray &data)
{
    QList<QByteArray> packets;
    int dataLength = data.length();
    int index = 0;
    int startAddress = 0x000000; // 起始地址

    while (index < dataLength) {
        QByteArray packet;

        // 添加站点号
        packet.append(station);

        // 添加标识符
        packet.append(sid);

        // 添加起始地址 (3字节)
        packet.append((startAddress >> 16) & 0xFF);
        packet.append((startAddress >> 8) & 0xFF);
        packet.append(startAddress & 0xFF);

        // 计算本包的数据长度，不超过count
        auto dataSize = qMin(static_cast<int>(count), dataLength - index);

        // 添加数据长度 (固定2字节 0x08)
        packet.append(0x08); // 假设数据长度字段固定为0x08
        packet.append(0x08);

        // 添加数据字节长 (1字节)
        packet.append(dataSize);

        // 添加数据Data
        packet.append(data.mid(index, dataSize));

        // 如果数据不足count，则填充0xFF
        if (dataSize < count) {
            packet.append(QByteArray(count - dataSize, 0xFF));
        }

        // 计算CRC校验码
        unsigned short crc = calculateCRC(packet.right(packet.size() - 1)); // 计算CRC时去掉CRC本身
        packet.append((crc >> 8) & 0xFF);
        packet.append(crc & 0xFF);

        // 添加到包列表
        packets.append(packet);

        // 更新索引和起始地址
        index += dataSize;
        startAddress += count/2; // 从第二个数据包开始地址偏移

        qDebug()<<"放进打包列表的数据有: "<<packet.toHex();
    }

    return packets;
}
